﻿using IPluginInterface.Loader;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace IPluginInterface
{
    public partial class PluginMainAoi : Form
    {
        string pluginPath;
        public delegate void PluginSelectedChanged(OneAoiMesPlugin onePlugin);
        public PluginSelectedChanged OnPluginSelectedChanged;
        private List<OneAoiMesPlugin> plugins = new List<OneAoiMesPlugin>();
        PluginHost host;
        public PluginMainAoi()
        {
            InitializeComponent();
            this.Text += "[加载插件中....]";
            this.Load += PluginMain_Load;
        }

        private void PluginMain_Load(object sender, EventArgs e)
        {
            LoadAllPluginAssembly(pluginPath);
            this.Text = "AOI插件管理";
        }

        /// <summary>
        /// 插件管理
        /// </summary>
        /// <param name="pluginPath">插件路径</param>
        /// <param name="pluginSelectedChanged">插件启用回调</param>
        public PluginMainAoi(string pluginPath, PluginSelectedChanged pluginSelectedChanged = null) : this()
        {
            this.pluginPath = pluginPath;
            OnPluginSelectedChanged = pluginSelectedChanged;
        }

          
        private void LoadAllPluginAssembly(string pluginPath)
        {
            Task.Run(() =>
            {

                host = new PluginHost(pluginPath);
                // events which allow actions to be performed after plug-ins are loaded
                host.PluginsLoaded += new EventHandler((a, b) => { /*MessageBox.Show("插件加载完成");*/ });
                //host.PluginsUnloaded += new EventHandler((a, b) => { MessageBox.Show("插件卸载完成"); });

                // load the example plug-in into a separate AppDomain
                if (host.LoadPlugins())
                {
                    // load the first available implementation of our example interface
                    Console.WriteLine("Loading first available implementation of {0}...", typeof(IAoiPlugin).Name);
                    //Sponsor<IPlugin> objectFromPlugin = host.GetImplementation<IPlugin>();

                    var sponsors = host.GetImplementations<IAoiPlugin>();
                    if (sponsors != null)
                    {
                        foreach(var one in sponsors)
                        {
                            OneAoiMesPlugin pluginInfo = new OneAoiMesPlugin(one);
                            plugins.Add(pluginInfo);
                            this.BeginInvoke(new Action<OneAoiMesPlugin>((p) =>
                            {
                                lvwPlugin.Items.Add(new ListViewItem(new string[] { Path.GetFileName(p.PluginFileName), p.Version?.ToString(), p.Tag, p.Description }));
                            }), pluginInfo);
                        }
                    }
                    else
                    {
                        Console.WriteLine("No implementations of {0} were found.", typeof(IAoiPlugin).Name);
                    }
                }
                else
                {
                    Console.WriteLine("Plug-ins were not loaded.");
                }
            });
        }

        private void btnChangePlugin_Click(object sender, EventArgs e)
        {
            if (lvwPlugin.SelectedIndices.Count == 0) return;
            if (OnPluginSelectedChanged != null)
            {
                host?.Dispose();
                OneAoiMesPlugin res = plugins[lvwPlugin.SelectedIndices[0]];
                res.LoadPlugin(res.PluginFileName);
                OnPluginSelectedChanged(plugins[lvwPlugin.SelectedIndices[0]]);
            }
        }
    }
}
